﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace mkv16
{
    [Serializable]
    public class Notion
    {
        Source source;
        public Notion(Source source)
        {
            this.source = source;
        }
        public Source Source
        {
            get { return source; }
        }
        public override string ToString()
        {
            return Source.ToString() + Name;
        }
        public virtual string Name
        {
            get { return source.Name; }
        }
    }

    [Serializable]
    public class Word : Notion
    {
        private string name;
        public Word(Source source, string name)
            : base(source)
        {
            this.name = name;
        }
        public override string Name
        {
            get { return name; }
        }
    }

    [Serializable]
    public class Fact : Notion
    {
        List<Notion> relatedNotions;
        DateTime date;
        public Fact(Source source, DateTime date, List<Notion> relatedNotions)
            : base(source)
        {
            this.relatedNotions = relatedNotions;
            this.date = date;
        }
        public Fact(Source source, DateTime date, params Notion[] relatedNotions)
            : base(source)
        {
            this.relatedNotions = new List<Notion>(relatedNotions);
            this.date = date;
        }
        public List<Notion> RelatedNotions
        {
            get { return relatedNotions; }
        }
        public DateTime Date
        {
            get { return date; }
        }
        public override string Name
        {
            get { return String.Join(" ", NotionsAsNames(relatedNotions.ToArray())); }
        }
        public static string[] NotionsAsNames(Notion[] notions)
        {
            var strings = new String[notions.Length];
            for (var i = 0; i < notions.Length; i++)
            {
                strings[i] = notions[i].Name;
            }

            return strings;
        }
    }

    [Serializable]
    public class Triple : Notion
    {
        Notion subject;
        Notion relation;
        Notion notion;
        public Triple(Source source, Notion subject, Notion relation, Notion notion)
            : base(source)
        {
            this.subject = subject;
            this.relation = relation;
            this.notion = notion;
        }
        public Notion Subject
        {
            get { return subject; }
        }
        public Notion Relation
        {
            get { return relation; }
        }
        public Notion Notion
        {
            get { return notion; }
        }
        public override string Name
        {
            get { return String.Format("{0} {1} {2}", subject.Name, relation.Name, notion.Name); }
        }
    }

    [Serializable]
    public class Source
    {
        string context;
        string name;
        public Source(string context, string name)
        {
            this.context = context;
            this.name = name;
        }
        public string Context
        {
            get { return context; }
        }
        public string Name
        {
            get { return name; }
        }
    }
}
